package com.cherry.androidcode.onresult

import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import io.reactivex.Observable

/**
 * @author 董棉生(dongmiansheng@parkingwang.com)
 * @since 18-9-27
 */

class AvoidOnResult(activity: AppCompatActivity) {

    private val avoidOnResultFragment: AvoidOnResultFragment = getAvoidOnResultFragment(activity)

    constructor(fragment: Fragment) : this(fragment.activity as AppCompatActivity)

    private fun getAvoidOnResultFragment(activity: AppCompatActivity): AvoidOnResultFragment {
        var avoidOnResultFragment: AvoidOnResultFragment? = findAvoidOnResultFragment(activity)
        if (avoidOnResultFragment == null) {
            avoidOnResultFragment = AvoidOnResultFragment()
            val fragmentManager = activity.supportFragmentManager
            fragmentManager
                    .beginTransaction()
                    .add(avoidOnResultFragment, TAG)
                    .commitAllowingStateLoss()
            fragmentManager.executePendingTransactions()
        }
        return avoidOnResultFragment
    }

    private fun findAvoidOnResultFragment(activity: AppCompatActivity): AvoidOnResultFragment? {
        return activity.supportFragmentManager.findFragmentByTag(TAG) as? AvoidOnResultFragment
    }

    fun startForResult(intent: Intent): Observable<ActivityResultInfo> {
        return avoidOnResultFragment.startForResult(intent)
    }

    fun startForResult(clazz: Class<*>): Observable<ActivityResultInfo> {
        val intent = Intent(avoidOnResultFragment.activity, clazz)
        return startForResult(intent)
    }

    /**
     * 提供默认的resultCode == Activity.RESULT_OK
     */
    fun startForResult(fromActivity: Activity, toActivityClz: Class<*>, intentData: ((intent: Intent) -> Unit)? = null): Observable<ActivityResultInfo> {
        return this.startForResult(Intent(fromActivity, toActivityClz).apply {
            intentData?.invoke(this)
        }).filter { it.resultCode == Activity.RESULT_OK }
    }

    fun startForResult(intent: Intent, callback: Callback) {
        avoidOnResultFragment.startForResult(intent, callback)
    }

    fun startForResult(clazz: Class<*>, callback: Callback) {
        val intent = Intent(avoidOnResultFragment.activity, clazz)
        startForResult(intent, callback)
    }

    interface Callback {
        fun onActivityResult(resultCode: Int, data: Intent?)
    }

    companion object {
        private const val TAG = "AvoidOnResult"
    }
}